package org.devlabs35.javamail;

import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.Part;
import javax.mail.internet.ContentType;
import javax.mail.internet.MimeMultipart;

import org.apache.commons.codec.binary.Base64;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

public class MultipartMailProcessor {

	private static String emailAltBodyContent = "Default";
	private static byte[] imageinBytes;
	private static Map<String, byte[]> imagesMap = new LinkedHashMap<String, byte[]>();
	private static List<byte[]> imageBytesList = new ArrayList<byte[]>();

	public static void main(String[] args) throws Exception {
		Message[] messages = ConnUtil.getMessages();
		for (int i = 0; i < messages.length; i++) {
			ContentType ct = new ContentType(messages[i].getContentType());
			System.out.println("Message Content type:" + ct.getPrimaryType() + ":" + ct.getSubType());
			// writePlaintextToFile(messages[i]);
			if (ct.getPrimaryType().equals("multipart")) {
				handleMultiPart(messages[i]);
			}
		}

		ConnUtil.closeResources();
	}

	public static void handleMultiPart(Message m) throws Exception {
		MimeMultipart content = (MimeMultipart) m.getContent();
		for (int i = 0; i < content.getCount(); i++) {
			BodyPart part = content.getBodyPart(i);
			ContentType ct = new ContentType(part.getContentType());
			System.out.println("#########Part Number: " + i + " #########");

			if (ct.getSubType().equals("alternative"))
				handleMultiPartAlternative(part);

			System.out.println("Content-type : " + ct.getPrimaryType() + "/" + ct.getSubType());
			System.out.println("Content : " + part.getContent());
			System.out.println("Part Filename : " + part.getFileName());

			if (part.isMimeType("image/png")) {
				System.out.println("Image Filename:" + part.getFileName());
				ContentFileSaver.writeToFile(part);
				imageBytesList.add(extractBytes(part));
			}

		}
		prepareHtml(imageBytesList, emailAltBodyContent);
	}

	public static void handleMultiPartAlternative(Part part) throws Exception {
		ContentType ct = new ContentType(part.getContentType());
		System.out.println("Content-type : " + ct.getPrimaryType() + "/" + ct.getSubType());
		System.out.println("Content : " + part.getContent());
		MimeMultipart mimeMultipart = (MimeMultipart) part.getContent();
		System.out.println("Parts Count: " + mimeMultipart.getCount());
		System.out.println(mimeMultipart.getBodyPart(0).getContentType());
		System.out.println(mimeMultipart.getBodyPart(1).getContentType());
		String plainText = (String) mimeMultipart.getBodyPart(0).getContent();
		emailAltBodyContent = (String) mimeMultipart.getBodyPart(1).getContent();
	}

	public static void prepareHtml(List<byte[]> imageBytesList, String altMailContent) throws Exception {
		Document doc = Jsoup.parse(altMailContent);
		Elements imgElements = doc.getElementsByTag("img");
		System.out.println("Images Size: " + imageBytesList.size());
		System.out.println(imgElements.size());
		for (int i = 0; i < imgElements.size(); i++) {
			System.out.println(imgElements.get(i).attr("src"));
			byte[] s = Base64.encodeBase64(imageBytesList.get(i));
			String base64String = new String(s);
			String srcAttribute = "data:image/png;base64," + base64String;
			imgElements.get(i).attr("src", srcAttribute);
		}

		FileOutputStream fileOutputStream = new FileOutputStream("C:\\temp\\" + "mailMsg.html");
		fileOutputStream.write(doc.toString().getBytes());
		fileOutputStream.close();
	}

	private static byte[] extractBytes(Part part) throws Exception {
		InputStream inputStream = (InputStream) part.getContent();
		byte[] bArray = new byte[inputStream.available()];
		while (((int) inputStream.available()) > 0) {
			int result = (int) (inputStream.read(bArray));
			if (result == -1)
				break;
		}
		return bArray;
	}
}